home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / TSR.SWG / 0016_Screen Saver TSR.pas < prev    next >
Pascal/Delphi Source File  |  1993-11-02  |  7KB  |  211 lines

  1. {
  2. From: ANDREW KEY
  3. Subj: Screen Save
  4. }
  5.  
  6. unit Scrnsavr;
  7. {$F+}
  8. (*************************************************************************)
  9. (*                        Screen Saver                                   *)
  10. (*                                                                       *)
  11. (*  Written by Jay A. Key -- Oct 1993                                    *)
  12. (*  Code may be modified and used freely.  Please mention my name        *)
  13. (*  somewhere in your docs or in the program itself.                     *)
  14. (*                                                                       *)
  15. (*  Self contained unit to install a text-mode screen saver in Turbo     *)
  16. (*  Pascal programs.  Simply include the following line in your code.    *)
  17. (*    uses ScrnSavr;                                                     *)
  18. (*                                                                       *)
  19. (*  It will initialize itself automatically, and will remove itself      *)
  20. (*  upon exit from your program, graceful exit or not.  Functions        *)
  21. (*  SetTimeOut and SetDelay are included if you wish to modify the       *)
  22. (*  default values.                                                      *)
  23. (*                                                                       *)
  24. (*  Warning: will not properly save and restore screens while running    *)
  25. (*  under the Turbo Pascal IDE.  Runs great from DOS.                    *)
  26. (*************************************************************************)
  27.  
  28. interface
  29.  
  30. uses Dos,Crt;
  31.  
  32. function NumRows: byte;          {Returns number of rows in current screen}
  33. function ColorAdaptor: boolean;  {TRUE if color video card installed}
  34. procedure SetTimeOut(T: integer); {Delay(seconds) before activation}
  35. procedure SetDelay(T: integer);  {Interval between iterations}
  36.  
  37. (************************************)
  38.  
  39. implementation
  40.  
  41. type
  42.   VideoArray = array[1..2000] of word;  {buffer to save video screen}
  43.  
  44. var
  45.   Timer: word;
  46.   Waiting: boolean;
  47.   OldInt15,                  {Keyboard interrupt}
  48.   OldInt1C,                  {Timer interrupt}
  49.   OldInt23,                  {Cntl-C/Cntl-Break handler}
  50.   ExitSave: pointer;
  51.   Position, Cursor: integer; {save and restore cursor positions}
  52.   VideoSave: VideoArray;
  53.   VideoMem: ^VideoArray;
  54.   TimeOut, Delay: integer;
  55.  
  56. procedure JumpToPriorIsr(p: pointer);
  57. {Originally written by Brook Monroe, "An ISR Clock", pg. 64,
  58.  PC Techniques Aug/Sep 1992}
  59.   inline($5b/$58/$87/$5e/$0e/$87/$46/$10/$89/$ec/$5d/$07/$1f/
  60.          $5f/$5e/$5a/$59/$cb);
  61.  
  62. function ColorAdaptor: boolean; assembler;
  63.   asm
  64.     int 11                   {BIOS call - get equipment list}
  65.     and al,$0010             {mask off all but bit 4}
  66.     xor al,$0010             {flip bit 4 - return val is in al}
  67.   end;
  68.  
  69. function NumRows: byte; assembler;  {returns number of displayable rows}
  70.   asm
  71.     mov ax,$40
  72.     mov es,ax
  73.     mov ax,$84
  74.     mov di,ax
  75.     mov al,[es:di]           {byte at [$40:$84] is number of rows in display}
  76.   end;
  77.  
  78. procedure HideCursor; assembler;
  79.   asm
  80.     mov ah,$03
  81.     xor bh,bh
  82.     int $10               {video interrupt}
  83.     mov Position,dx       {save cursor position}
  84.     mov Cursor,cx         {and type}
  85.     mov ah,$01
  86.     mov ch,$20
  87.     int $10               {video interrupt - hide cursor}
  88.   end;
  89.  
  90. procedure RestoreCursor; assembler;
  91.   asm
  92.     mov ah,$02
  93.     xor bh,bh
  94.     mov dx,Position       {get old position}
  95.     int $10               {video interrupt - restore cursor position}
  96.     mov cx,Cursor         {get old cursor type}
  97.     mov ah,$01
  98.     int $10               {video interrupt - restore cursor type}
  99.   end;
  100.  
  101. procedure RestoreScreen;
  102.   begin
  103.     VideoMem^ := VideoSave;  {Copy saved image back onto video memory}
  104.     RestoreCursor;
  105.   end;
  106.  
  107. procedure SaveScreen;
  108.   begin
  109.     VideoSave := VideoMem^;  {Copy video memory to array}
  110.     HideCursor;
  111.   end;
  112.  
  113. procedure DispMsg;  {simple stub-out for displaying YOUR message(s),
  114.                      pictures, etc...use your imagination!!!}
  115.   begin
  116.     ClrScr;
  117.     GotoXY(random(50),random(23));
  118.     writeln('This would normally be something witty!');
  119.   end;
  120.  
  121. procedure NewInt15(Flags,CS,IP,AX,BX,CX,DX,
  122.                    SI,DI,DS,ES,BP:WORD); interrupt; {keyboard handler}
  123.   begin
  124.     Timer:=0;                     {Reset timer}
  125.     if Waiting then               {Screen saver activated?}
  126.       begin
  127.         RestoreScreen;            {Restore saved screen image}
  128.         Waiting:= FALSE;          {De-activate screen saver}
  129.         Flags:=(Flags and $FFFE); {Tell BIOS to ignore current keystroke}
  130.       end
  131.     else
  132.       JumpToPriorISR(OldInt15);   {call original int 15}
  133.   end;
  134.  
  135. procedure NewInt1C; interrupt;    {timer interrupt}
  136.   begin
  137.     Inc(Timer);                   {Increment timer}
  138.     if Timer>TimeOut then         {No key hit for TimeOut seconds?}
  139.       begin
  140.         Waiting := TRUE;          {Activate screen saver}
  141.         SaveScreen;               {Save image of video memory}
  142.         DispMsg;                  {Display your own message}
  143.         Timer := 0;               {Reset timer}
  144.       end;
  145.     if waiting then               {Is saver already active?}
  146.       begin
  147.         if Timer>Delay then       {Time for next message?}
  148.           begin
  149.             Timer := 0;           {Reset timer}
  150.             DispMsg;              {Display next message}
  151.           end;
  152.       end;
  153.     JumpToPriorISR(OldInt1C);     {Chain to old timer interrupt}
  154.   end;
  155.  
  156. procedure ResetIntVectors;        {Restores Intrrupt vectors to orig. values}
  157.   begin
  158.     SetIntVec($15,OldInt15);
  159.     SetIntVec($1C,OldInt1C);
  160.     SetIntVec($23,OldInt23);
  161.   end;
  162.  
  163. procedure NewInt23; interrupt;    {Called to handle cntl-c/brk}
  164.   begin
  165.     ResetIntVectors;              {Restore old interrupt vectors}
  166.     JumpToPriorISR(OldInt23);     {Chain to original int 23h}
  167.   end;
  168.  
  169. procedure MyExit; far;            {exit code for unit}
  170.   begin
  171.     ResetIntVectors;              {Restore old interrupt vectors}
  172.     ExitProc:=ExitSave;           {Restore old exit code}
  173.   end;
  174.  
  175. procedure SetVideoAddress;        {Returns pointer to text video memory}
  176.   begin
  177.     if ColorAdaptor then
  178.       VideoMem := ptr($B000,$0000)
  179.     else
  180.       VideoMem := ptr($B800,$0000);
  181.   end;
  182.  
  183. procedure SetTimeOut(T: integer); {Set delay(seconds) before activation}
  184.   begin
  185.     TimeOut:=Round(T*18.2);
  186.   end;
  187.  
  188. procedure SetDelay(T: integer);  {Set interval between iterations}
  189.   begin
  190.     Delay:=Round(T*18.2);
  191.   end;
  192.  
  193. {Initialize unit}
  194. begin
  195.   SetVideoAddress;             {Set up address for video memory}
  196.   Waiting := FALSE;            {Screen saver initially OFF}
  197.   Timer := 0;                  {Reset timer}
  198.   ExitSave := ExitProc;        {Save old exit routine}
  199.   ExitProc := @MyExit;         {Install own exit routine}
  200. {Install user defined int vectors}
  201.   GetIntVec($15,OldInt15);     {Keyboard handler}
  202.   SetIntVec($15,@NewInt15);
  203.   GetIntVec($1c,OldInt1C);     {Timer int}
  204.   SetIntVec($1c,@NewInt1C);
  205.   GetIntVec($23,OldInt23);     {Cntl-C/Brk handler}
  206.   SetIntVec($23,@NewInt23);
  207.   SetTimeOut(120);
  208.   SetDelay(15);
  209. end.
  210.  
  211.